<template>
  <div class="minimap-container">
    <!-- 主内容区域 -->
    <div ref="mainContent" class="main-content" @scroll="handleScroll">
      <slot></slot>
      <!-- <div ref="mainRef" style="width: fit-content;height: fit-content;">
        <slot></slot>
      </div> -->
    </div>

    <!-- 小地图 -->
    <div class="minimap-wrapper" draggable="true" ref="minMapRef"
      :style="{ transform: `translate(${this.minMapX}px,${this.minMapY}px)` }" @dragend="minMapEndDrag">
      <canvas ref="minimapCanvas" class="minimap-canvas"></canvas>
      <div ref="viewportIndicator" draggable="true" class="viewport-indicator" :style="{
        ...viewportStyle(),
        transform: `translate(${this.viewportX}px,${this.viewportY}px)`
      }" @drag.stop="handleDrag" @dragend.stop="endDrag"></div>

    </div>
  </div>
</template>

<script>
import html2canvas from 'html2canvas'
// import throttle from 'lodash/throttle'
import { throttle } from '@/utils/utils.js'
export default {
  name: 'HtmlMinimap',
  props: {
    scale: {
      type: Number,
      default: 0.15
      // default: 0.001

    },
    updateInterval: {
      type: Number,
      default: 300
    }
  },
  data () {
    return {
      observer: null,
      isDragging: false,
      contentWidth: 0,
      contentHeight: 0,

      viewportX: 0,
      viewportY: 0,
      // 
      minMapX: 0,
      minMapY: 0
    }
  },

  mounted () {

    this.initMinimap()
    this.setupMutationObserver()
    window.addEventListener('resize', this.handleResize)

  },
  beforeDestroy () {
    this.cleanup()
  },
  methods: {

    viewportStyle () {
      if (!this.$refs.mainContent) {
        return {
        }
      }
      return {
        width: `${this.$refs.mainContent.clientWidth * this.scale}px`,
        height: `${this.$refs.mainContent.clientHeight * this.scale}px`,
      }
    },

    // 初始化小地图
    async initMinimap () {
      await this.$nextTick()
      this.updateContentSize()
      this.drawMinimap()
    },

    // 绘制缩略图
    drawMinimap: throttle(function () {
      if (!this.$refs.mainContent) return
      html2canvas(
        // this.$refs.mainRef
        this.$slots.default[0].elm
        , {
          scale: this.scale,
          // width: this.$refs.mainContent.scrollWidth,
          // height: this.$refs.mainContent.scrollHeight ,
          windowWidth: this.$refs.mainContent.scrollWidth + 100,
          windowHeight: this.$refs.mainContent.scrollHeight + this.$refs.mainContent.scrollTop + 200,
          // windowHeight: this.$refs.mainContent.scrollHeight,
          useCORS: true,
          logging: false
        }).then(canvas => {

          this.$refs.minimapCanvas.width = canvas.width
          this.$refs.minimapCanvas.height = canvas.height
          const ctx = this.$refs.minimapCanvas.getContext('2d')
          ctx.drawImage(canvas, 0, 0)
        })
    }, 200),

    // 更新内容尺寸
    updateContentSize () {
      if (this.$refs.mainContent) {
        this.contentWidth = this.$refs.mainContent.scrollWidth
        this.contentHeight = this.$refs.mainContent.scrollHeight
      }
    },

    // 设置DOM监听
    setupMutationObserver () {
      this.observer = new MutationObserver(this.drawMinimap)
      this.observer.observe(
        // this.$refs.mainContent,
        this.$slots.default[0].elm,
        {
          subtree: true,
          childList: true,
          attributes: true,
          characterData: true
        })
    },

    // 处理滚动事件
    handleScroll: throttle(function (e) {
      if (this.isDragging) {
        return
      }
      this.viewportX = Math.max(e.target.scrollLeft * this.scale, 0)
      this.viewportY = Math.max(e.target.scrollTop * this.scale, 0)
    }, 50),

    // 处理窗口尺寸变化
    handleResize () {
      this.updateContentSize()
      this.drawMinimap()
    },
    // 小地图拖拽
    minMapEndDrag (e) {

      this.minMapX = this.minMapX + e.offsetX - e.target.clientWidth / 2
      this.minMapY = this.minMapY + e.offsetY - e.target.clientHeight / 2
    },
    // 视口标记拖拽
    endDrag (e) {
      // console.log('endDrag', e)
      this.viewportX = Math.max(this.viewportX + e.offsetX - e.target.clientWidth / 2, 0)
      this.viewportY = Math.max(this.viewportY + e.offsetY - e.target.clientHeight / 2, 0)
      this.viewportX = Math.min(this.viewportX, this.$refs.minMapRef.clientWidth - e.target.clientWidth)
      this.viewportY = Math.min(this.viewportY, this.$refs.minMapRef.clientHeight - e.target.clientHeight)
      const rect = this.$refs.minimapCanvas.getBoundingClientRect()
      const scale = this.scale

      const scrollX = (e.clientX - rect.left) / scale -
        this.$refs.mainContent.clientWidth / 2
      const scrollY = (e.clientY - rect.top) / scale -
        this.$refs.mainContent.clientHeight / 2

      setTimeout(() => {
        this.$refs.mainContent.scrollTo({
          left: Math.max(0, scrollX),
          top: Math.max(0, scrollY),
          behavior: 'auto'
        })
        this.isDragging = false
      }, 100)
    },

    // 处理拖拽视口标记
    handleDrag: throttle(function (e) {
      // console.log('handleDrag', e)
      if (!this.$refs.mainContent) return
      this.isDragging = true
      const rect = this.$refs.minimapCanvas.getBoundingClientRect()
      const scale = this.scale

      const scrollX = (e.clientX - rect.left) / scale -
        this.$refs.mainContent.clientWidth / 2
      const scrollY = (e.clientY - rect.top) / scale -
        this.$refs.mainContent.clientHeight / 2

      this.$refs.mainContent.scrollTo({
        left: Math.max(0, scrollX),
        top: Math.max(0, scrollY),
        behavior: 'auto'
      })
    }, 50),

    // 清理资源
    cleanup () {
      this.observer && this.observer.disconnect()
      window.removeEventListener('resize', this.handleResize)
    }
  }
}
</script>

<style scoped lang="less">
.minimap-container {
  position: relative;
  height: 100vh;
  width: 100%;
}

.main-content {
  height: 100%;
  width: calc(100% - 10px);
  overflow: auto;
  border-right: 1px solid #eee;
}

.minimap-wrapper {
  position: fixed;
  right: 20px;
  bottom: 20px;
  border: 1px solid #999;
  background: rgba(255, 255, 255, 0.9);
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  border-radius: 4px;
  z-index: 1000;
  // overflow: hidden;
}

.viewport-indicator {
  position: absolute;
  top: 0;
  left: 0;
  border-radius: 4px;
  border: 1px solid #1E838E;
  cursor: grab;
  transition: transform 0.1s ease;

}

.viewport-indicator:active {
  cursor: grabbing;
}
</style>